﻿//  Copyright (c) 2010 Ray Liang (http://www.dotnetage.com)
//  Dual licensed under the MIT and GPL licenses:
//  http://www.opensource.org/licenses/mit-license.php
//  http://www.gnu.org/licenses/gpl.html
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Web.Mvc;
using System.Web.UI;

namespace DNA.Mvc.jQuery
{
    public abstract class NodeComponentBase<TContainer, TNode> : NavigableView, IComponentItemContainer<TNode>
        where TNode : NodeComponentBase<TContainer, TNode>
    {
        private TNode parent;
        private TContainer container;
        private IList<TNode> items;
        private int level = 0;

        public int Level
        {
            get { return level; }
            internal set { level = value; }
        }

        public NodeComponentBase() { }

        public NodeComponentBase(INavigable node) : base(node) { }

        public TContainer Container
        {
            get { return container; }
            internal set { container = value; }
        }

        public TNode Parent
        {
            get { return parent; }
            internal set { parent = value; }
        }

        /// <summary>
        /// Gets/Sets the children node items.
        /// </summary>
        public IList<TNode> Children
        {
            get
            {
                if (items == null)
                    items = new List<TNode>();
                return items;
            }
            set
            {
                items = value;
            }

        }

        IList<TNode> IComponentItemContainer<TNode>.Items
        {
            get { return this.Children; }
        }

        public override string TagName
        {
            get
            {
                return "li";
            }
        }

        public override void RenderContent(System.Web.UI.HtmlTextWriter writer)
        {
            if (!Template.IsEmpty)
            {
                Template.WriteTo(writer);
                //base.RenderContent(writer);
            }
            else
                RenderNodeContent(writer);

            if (Children.Count > 0)
            {
                this.RenderChildrenBeginTag(writer);
                foreach (var item in items)
                    this.RenderChildrenNode(writer, item);
                this.RenderChildrenEndTag(writer);
            }
        }

        public virtual void RenderNodeContent(System.Web.UI.HtmlTextWriter writer)
        {
            var builder = new NodeUIBuilder();

            if (!string.IsNullOrEmpty(this.NavigateUrl))
                builder.WriteBeginLink(this);


            if (!string.IsNullOrEmpty(this.ImageUrl))
                builder.WriteImage(this);

            builder.WriteTitle(this, new { style = "padding:2px;cursor:default;display:inline-block;" });

            if (!string.IsNullOrEmpty(this.NavigateUrl))
                builder.WriteEndTag("a");

            writer.Write(builder.ToString());
        }

        public virtual void RenderChildrenBeginTag(HtmlTextWriter writer)
        {
            writer.WriteBeginTag("ul");
            writer.WriteAttribute("class", NodeContainerCssClass);
            writer.Write(HtmlTextWriter.TagRightChar);
        }

        protected virtual string NodeContainerCssClass
        {
            get { return "ui-helper-reset"; }
        }

        public virtual void RenderChildrenNode(System.Web.UI.HtmlTextWriter writer, TNode node)
        {
            node.Render(writer);
        }

        public virtual void RenderChildrenEndTag(HtmlTextWriter writer)
        {
            writer.WriteEndTag("ul");
        }

        protected virtual void OnItemAdded(TNode item) 
        {
            item.Container = this.container;
            item.Parent = (TNode)this;
            item.Level = this.Level + 1;
        }

        void IComponentItemContainer<TNode>.OnItemAdded(TNode item)
        {
            this.OnItemAdded(item);
        }
    }
}
